//
//  HMMapViewController.m
//  MeiTuanHD
//
//  Created by Hanyang Li on 2021/9/18.
//

#import "HMMapViewController.h"
#import <MapKit/MapKit.h>
#import "HMBusinessModel.h"
#import "HMAnnotationModel.h"
#import "HMMateTool.h"
#import "HMHomeNavView.h"
#import "HMCategoryViewController.h"
#import "HMCategoryModel.h"

@interface HMMapViewController ()<MKMapViewDelegate,DPRequestDelegate>

/** 地图 */
@property (weak, nonatomic) IBOutlet MKMapView *mapView;

/** 位置管理器进行授权操作 --> iOS8以后必须这么做*/
@property (nonatomic, strong) CLLocationManager *locationManager;

/** 大头针的模型数据 */
@property(nonatomic, strong)NSMutableArray *dataArray;

/* 通知发送选中的分类名 */
@property (nonatomic, copy) NSString *selectCategoryName;

/* 分类导航栏 View */
@property (nonatomic, strong) HMHomeNavView *categoryView;

@end

@implementation HMMapViewController


#pragma mark MapView 懒加载
- (NSMutableArray *)dataArray{
    if(_dataArray==nil){
        _dataArray =  [NSMutableArray array];
    }
    return _dataArray;
}


- (void)viewDidLoad {
    
    [super viewDidLoad];
  
    //创建位置管理器并授权
    self.locationManager = [CLLocationManager new];
    //授权需要做2件事: 1.调用授权方法 2.配置 plist 键值对
    if([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
        //前台授权的方法 --> 当用户正在使用程序的时候
        [self.locationManager requestWhenInUseAuthorization];
    }
    
    //跟踪用户的位置
    self.mapView.userTrackingMode  = MKUserTrackingModeFollow;
    
    //下面的方法，也可以显示用户的位置, 但是不会跟踪到合理的位置显示大小
    // self.mapView.showsUserLocation = YES;
    
    //设置地图代理
    self.mapView.delegate = self;
    
    //注册选择分类通知
    [HMNotificationCenter addObserver:self selector:@selector(categoryDidChangeNotifacation:) name:HMCategoryDidChangeNotifacation object:nil];
    
    
    //导航栏
    self.navigationItem.title = @"地图";
    //1.返回 Item
    UIBarButtonItem *backItem = [UIBarButtonItem barbuttonItemWithTarget:self action:@selector(backButtonClick) icon:@"icon_back" highlighticon:@"icon_back_highlighted"];
    
    //2.分类 Item
    HMHomeNavView *categoryView = [HMHomeNavView homeNavView];
    UIBarButtonItem *categoryItem = [[UIBarButtonItem alloc] initWithCustomView:categoryView];
    categoryItem.width = 160;
    [categoryView setTitle:@"全部分类"];
    [categoryView setSubtitle:@""];
    [categoryView setIcon:@"icon_category_-1" hightIcon:@"icon_category_highlighted_-1"];
    //属性赋值
    self.categoryView =categoryView;
    //添加按钮点击事件
    [categoryView addTarget:self action:@selector(categoryClick)];
    
    self.navigationItem.leftBarButtonItems = @[backItem,categoryItem];
}


#pragma mark 分类按钮点击
-(void)categoryClick{
    //1.创建内容控制器
    HMCategoryViewController *categoryVC = [HMCategoryViewController new];
    
    //2.设置 popover 相关属性
    categoryVC.modalPresentationStyle = UIModalPresentationPopover;
    categoryVC.popoverPresentationController.barButtonItem = self.navigationItem.leftBarButtonItems[1];
    
    //3.模态显示控制器
    [self presentViewController:categoryVC animated:YES completion:nil];
    
}

#pragma mark 通知相关方法

#pragma mark  - 分类通知
-(void)categoryDidChangeNotifacation:(NSNotification*)notification{
    
    //1.左边模型
    HMCategoryModel *selectCategoryModel =notification.userInfo[HMCategoryModelKey];
    //2.右边子标题
    NSString *selectCategorySubtitle = notification.userInfo[HMCategorySubtitleKey];
    
    /**
     1. 发送右边 右边有值，且不等于 “全部”
     2. 发送左边 没有子分类数据，就发送左边，且不等于"全部”
     3. 不发送 没有需求进行筛选 或者 点击了 @“全部分类”
     */
    //获取选中的分类 --> 为了发送请求
    
    //1.发送左边
    if(selectCategorySubtitle == nil || [selectCategorySubtitle isEqualToString:@"全部"]){
        self.selectCategoryName = selectCategoryModel.name;
    }else{
        //2.发送右边
        self.selectCategoryName = selectCategorySubtitle;
    }
    
    //3.不发送
    if([self.selectCategoryName isEqualToString:@"全部分类"]){
        self.selectCategoryName = nil;
    }
    
    //3.1 获取导航栏 View 直接更新标题
    [self.categoryView setTitle:selectCategoryModel.name];
    //3.2 设置子标题
    [self.categoryView setSubtitle:selectCategorySubtitle];
    //3.2 设置图标
    [self.categoryView setIcon:selectCategoryModel.icon  hightIcon:selectCategoryModel.highlighted_icon];
    //4.取消 popover 的显示
    [self dismissViewControllerAnimated:YES completion:nil];
    
    //5.移除地图的大头针数据
    [self.mapView removeAnnotations:self.mapView.annotations];
    
    //6.移除临时数组的数据
    [self.dataArray removeAllObjects];
    
    //7.调用接口，发送分类的参数
    [self mapView: self.mapView regionDidChangeAnimated:YES];
}

#pragma mark 移除观察者
- (void)dealloc{
    [HMNotificationCenter removeObserver:self];
}


#pragma mark MapView 代理方法

#pragma mark 当添加大头针模型的时候，返回大头针 View 的方法
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
    
    //1.如果 return nil，那么就代表，不需要自定义大头针 View, 系统会按照自己的默认值来处理大头针
    if([annotation isKindOfClass:[MKUserLocation class]]){
        return nil;
    }
    
    /**
    1.  大头针的模型是有2种: 1 种是系统显示用户位置的大头针模型，第2种是自定义的大头针模型
    2. 需要判断系统的显示用户位置的大头针，不需要自定义
     MKUserLocation:
     MKAnnotationModel:
     */
    static NSString *identifier = @"annotation";
    MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
   
    if(annoView == nil){
        annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        //一旦实现了自定义大头针的方法,那么可以点击大头针的属性就失效
        annoView.canShowCallout = YES;
    }
    
    HMAnnotationModel *annotationModel = (HMAnnotationModel *)annotation;
    annoView.image = [UIImage imageNamed:annotationModel.icon];
    return annoView;
}

#pragma mark 区域完成改变的方法
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
    
    //1.创建 DPAPI 对象
    DPAPI *dpapi = [DPAPI new];
    
    //2.拼接参数
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    
    //2.1jin纬度
    //region: 包含2个参数. 1 中心点经纬度 2.显示的跨度
    params[@"latitude"] = @(self.mapView.region.center.latitude);
    params[@"longitude"] = @(self.mapView.region.center.longitude);
    
    //2.2 分类
    if(self.selectCategoryName){
        params[@"category"] = self.selectCategoryName;
    }
    
    //3.发送请求
    [dpapi requestWithURL:@"v1/business/find_businesses" params:params delegate:self];
    
    NSLog(@"regionDidChangeAnimated");
}

#pragma mark 请求成功
- (void)request:(DPRequest *)request didFinishLoadingWithResult:(id)result{
    
    //NSLog(@"成功");
    /**
     如果希望大头针数据，每次只保持一定的数量，那么可以每次请求后删除之前的数据，后面的模型判断(第三步)可以不用写  -- --> 建议使用这种
     如果希望大头针数据，可以保持很多个，那么删除旧的代表，不应该在这里写，可以放在通知发送请求的地方写
     */
    //方式一 添加之前 删除之前的大头针的数据
    //每次分类请求删除之前的数据
//    [self.mapView removeAnnotations:self.mapView.annotations];
//    [self.dataArray removeAllObjects];
    
    //1.获取模型数据
    for (NSDictionary *dict in result[@"businesses"]) {
        [self.dataArray addObject:[HMBusinessModel yy_modelWithJSON:dict]];
    }
    
    //2.添加大头针
    for (HMBusinessModel *businessModel in self.dataArray) {
        HMAnnotationModel *annotationModel = [HMAnnotationModel new];
        annotationModel.coordinate = CLLocationCoordinate2DMake(businessModel.latitude,businessModel.longitude);
        annotationModel.title = businessModel.name;
        annotationModel.subtitle = businessModel.address;
        
        //图像
        //应该根据 plist 列表来返回对应的图像信息 --> map_icon;map_icon;
        
        annotationModel.icon = [HMMateTool mapNameWithBusinessModel:businessModel];
        
        //3.如果已经添加，那么就不添加了
        /**
         containsObject: 内部会调用 isEqual 方法
         isEqual 方法： 比较的是哈希值，其中包括了时间
         解决方案: 重写  isEqual  方法，自己制定要比较的部分
         比较的是大头针模型数据, 就应该重写此模型的 isEqual  方法
         */
        if([self.mapView.annotations containsObject:annotationModel]){
            continue;
        }else{
            //添加到地图里
            [self.mapView addAnnotation:annotationModel];
        }
    }

}

#pragma mark 返回失败
- (void)request:(DPRequest *)request didFailWithError:(NSError *)error{
    NSLog(@"失败");
}

#pragma mark 返回按钮
-(void)backButtonClick{
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end
